import { Inject, Middleware, httpError } from '@midwayjs/core';
import { Context, NextFunction } from '@midwayjs/koa';
import { JwtService } from '@midwayjs/jwt';
import { Config } from '@midwayjs/core';
import { Jwt } from '../model';

@Middleware()
export class JwtMiddleware {
  @Inject()
  jwtService: JwtService;
  @Config('jwt')
  jwt: Jwt;
  apiWhiteList: string[] = ['/user/login', '/user/code', '/user/adminLogin','/announcement/list','/announcement/byId'];
  resolve() {
    return async (ctx: Context, next: NextFunction) => {
      // 判断下有没有校验信息
      if (!ctx.headers['authorization']) {
        throw new httpError.UnauthorizedError('请先登录');
      }
      let token = ctx.get('authorization');
      if (token.split('Bear_').length === 1) {
        try {
          await this.jwtService.verify(token, {
            complete: true,
          });

          const res = this.jwtService.decode(token);
          const exp = Number(res['exp'] + '000');
          const now = Date.now();
          const sixHour = 1000 * 60 * 60 * 6;
          if (exp - now <= sixHour) {
            const newToken = await this.jwtService.sign({ sign: res['sign'] });
            //将新token放入Authorization中返回给前端
            ctx.set('Authorization', newToken);
          }
          if (typeof res['sign'] === 'string') {
            ctx.state.user = JSON.parse(res['sign'])
          } else {
            ctx.state.user = res['sign']
          }

        } catch (error) {
          throw new httpError.ForbiddenError('无效账号');
        }
      } else {
        token = token.split('Bear_')[1]
        try {
          await this.jwtService.verify(token, this.jwt.adminSecret,{
            complete: true,
          });
          const res = this.jwtService.decode(token);
          const exp = Number(res['exp'] + '000');
          const now = Date.now();
          const sixHour = 1000 * 60 * 60 * 6;
          if (exp - now <= sixHour) {
            const newToken = await this.jwtService.sign({ sign: res['sign'] }, this.jwt.adminSecret);
            //将新token放入Authorization中返回给前端
            ctx.set('Authorization', `Bear_${newToken}`);
          }
          if (typeof res['sign'] === 'string') {
            ctx.state.user = JSON.parse(res['sign'])
          } else {
            ctx.state.user = res['sign']
          }
        } catch (error) {
          throw new httpError.ForbiddenError('无效账号');
        }
      }

      await next();
    };
  }

  // 配置忽略鉴权的路由地址
  public match(ctx: Context): boolean {
    const ignore = this.apiWhiteList.includes(ctx.path);
    return !ignore;
  }
}
